#include <stdio.h>

struct BIT16_S {
    uint8_t high0;
    uint8_t high1;
};

struct BIT32_S {
    uint8_t high0;
    uint8_t high1;
    uint8_t high2;
    uint8_t high3;
};

struct BIT64_S {
    uint8_t high0;
    uint8_t high1;
    uint8_t high2;
    uint8_t high3;
    uint8_t high4;
    uint8_t high5;
    uint8_t high6;
    uint8_t high7;
};

uint16_t swap16_be_le(uint16_t be)
{
    struct BIT16_S* bls = (struct BIT16_S*)&be;
    struct BIT16_S bls_new;
    bls_new.high0 = bls->high1;
    bls_new.high1 = bls->high0;

    return *(uint16_t*)&bls_new;
}

uint32_t swap32_be_le(uint32_t be)
{
    struct BIT32_S* bls = (struct BIT32_S*)&be;
    struct BIT32_S bls_new;
    bls_new.high0 = bls->high3;
    bls_new.high1 = bls->high2;
    bls_new.high2 = bls->high1;
    bls_new.high3 = bls->high0;

    return *(uint32_t*)&bls_new;
}

uint64_t swap64_be_le(uint64_t be)
{
    struct BIT64_S* bls = (struct BIT64_S*)&be;
    struct BIT64_S bls_new;
    bls_new.high0 = bls->high7;
    bls_new.high1 = bls->high6;
    bls_new.high2 = bls->high5;
    bls_new.high3 = bls->high4;
    bls_new.high4 = bls->high3;
    bls_new.high5 = bls->high2;
    bls_new.high6 = bls->high1;
    bls_new.high7 = bls->high0;
    
    return *(uint64_t*)&bls_new;
}

bool is_bigending1()
{
    union BE_LE_U {
        uint8_t low_byte;
        uint16_t low16_bit;
    } blu;

    blu.low16_bit = 0x1234;
    return blu.low_byte == 0x12;
}

bool is_bigending2()
{
    static union { char c[4]; uint32_t l; } endian_test = { { 'l', '?', '?', 'b' } };
    return ((char)endian_test.l == 'b');
}


int main()
{
    uint64_t n = 0x12345678aabbccdd;
    uint16_t n16 = 0x1234;
    uint32_t n32 = 0x12345678;

    printf("0x12345678aabbccdd : 0x%llx\n", swap64_be_le(n));
    printf("0x1234 : 0x%x\n", swap16_be_le(n16));
    printf("0x12345678 : 0x%lx\n", swap32_be_le(n32));
    return 0;
}